# -*- coding:utf-8 -*-
"""
=============================
this is a feibot product,
all rights reserved.
www.feibot.com
@author: Gu Tianyuan
@email: g@feibot.com
@time: ${DATE}:${TIME}
@product: ${PRODUCT_NAME}
=============================
"""
import multiprocessing
import threading
import queue
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QDialog, QApplication, QFileDialog, QMessageBox
import gtyIO.gtyIoTools
from uiFiles import ui_eventSettingDialog, ui_Inputdialog
from gtyTools import gtyLog, gtyTypes
import time
from gtyConfig import language, systemConfig
import uiTools
from gtyTools import tools
import sys
import os

copy_file_result_queue = queue.Queue()
copy_file_process_queue = queue.Queue()


class EventSettingDialog(QDialog, ui_eventSettingDialog.Ui_eventSettingDialog):

    def __init__(self, mainPage, eventQ, parent=None):
        super(EventSettingDialog, self).__init__(parent)
        self.setupUi(self)
        uiTools.centerAndSetIcon(self)
        self.setWindowIcon(QIcon(systemConfig.param.windowLogoPath))
        self.mainPage = mainPage
        self.eventQ = eventQ

        # 配置文件对象
        self.configHandlers = gtyTypes.ConfigHandlers()
        self.releaseMode = self.configHandlers.state.read("machine", "releaseMode")
        self.machineId = ""
        self.eventId = ""
        self.ReeventId = ""
        self.eventName = ""
        self.machinePosition = ""
        self.configFileName = ""
        self.recordFileDir = ""
        with open('./Newevent.ini', 'r') as f:
            self.ReeventId = f.readline().strip()
        self.updateEventConfigInfo()

        # 建立连接
        self.readConfigFileButton.clicked.connect(self.readConfigFileFromU)
        self.downloadConfigFileButton.clicked.connect(self.downloadConfigFileFromServer)
        self.uploadRecordFileButton.clicked.connect(self.uploadRecordFileToServer)
        self.eraseRecordDataBtn.clicked.connect(self.deleteRecord)
        self.exportThisEventDataButton.clicked.connect(lambda: self.exportData2Disk(False))
        self.exportAllDataButton.clicked.connect(lambda: self.exportData2Disk(True))
        self.setracenum_btn.clicked.connect(self.setRandomNum)

        # 根据文件名，更新此页面的显示
        self.mainPage.eventEngine.eventList["ui_updateCurrentEventConfigFileName"].connect(self.updateEventConfigInfo)
        # 下载赛事配置文件的结果
        self.mainPage.eventEngine.eventList["ui_downloadEventConfigFileFromServerResult"].connect(
            self.loadConfigFileDownloadedFromServer)
        #
        self.mainPage.eventEngine.eventList["ui_uploadResultFileToServer"].connect(self.handleFileUploadResult)

        if self.releaseMode == 'release':
            self.eraseRecordDataBtn.setHidden(True)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_progress)
        self.timer.start(100)
        # 处理不同的语言
        self.language = language.lanFromFile()
        self.label_19.setText(language.eventSetting_eventId)
        self.label_17.setText(language.eventSetting_eventName)
        self.label_18.setText(language.eventSetting_machinePosition)
        self.label_20.setText(language.eventSetting_configFile)
        self.label_21.setText(language.eventSetting_recordFile)
        self.exportThisEventDataButton.setText(language.eventSetting_exportThisData)
        self.exportAllDataButton.setText(language.eventSetting_exportAllData)
        self.eraseRecordDataBtn.setText(language.eventSetting_deleteDataFile)
        self.readConfigFileButton.setText(language.eventSetting_readConfigFileFromDisk)
        self.downloadConfigFileButton.setText(language.eventSetting_downLoadConfigFile)
        self.uploadRecordFileButton.setText(language.eventSetting_uploadFile)
        self.returnButton.setText(language.eventSetting_back)
        self.setracenum_btn.setText(language.eventSetting_setRaceNumber)
        self.setWindowTitle("Event")
        self.setGeometry(-200, -200, self.width(), self.height())
        if self.ReeventId and self.ReeventId.strip() != '':
            self.label_display.setText(f"set Race ID to {self.ReeventId}！")

    # 发生事件
    def sendEvent(self, task, eventName, eventData=None):
        if eventData is None:
            eventData = []
        e = [eventName, eventData]
        print(__file__, task, e)
        try:
            if task.upper() in self.eventQ.keys():
                print(__file__, "1", e, self.eventQ)
                self.eventQ[task.upper()].put(e)
        except Exception as e:
            print(e)

    # 从U盘复制配置文件
    def readConfigFileFromU(self):
        # 1.获取U盘路径
        uDiskDir = gtyIO.gtyIoTools.getUDiskPath(self)
        if 'error:' not in uDiskDir:
            res = QFileDialog.getOpenFileName(self, 'select file', '/media/feibot/' + uDiskDir + '/',
                                              'event config file(*.ecg)')
        else:
            res = QFileDialog.getOpenFileName(self, 'select file', '/media/feibot/', 'event config file(*.ecg)')
        eventConfigFileName = res[0]
        if '.ecg' not in eventConfigFileName:
            return
        eventConfigFileNameWithoutPath = eventConfigFileName.split('/')[-1]
        self.label_configFile.setText(eventConfigFileNameWithoutPath)
        print(__file__, eventConfigFileNameWithoutPath)
        # 2. 删除原来的配置文件
        cmd = str('cp ' + eventConfigFileName + ' ' + os.path.join(systemConfig.configFilePath
                                                                   , 'newEventConfigFile'))
        os.system(cmd)
        os.system('rm ' + os.path.join(systemConfig.configFilePath, 'ec_*.ecg'))
        # 3. 将这个文件复制到config目录下
        cmd = str('mv ' + os.path.join(systemConfig.configFilePath, 'newEventConfigFile') + ' ' +
                  os.path.join(systemConfig.configFilePath, eventConfigFileNameWithoutPath))
        os.system(cmd)
        # 4. 加载赛事配置文件的内容
        self.sendEvent('IO', 'file_loadEventConfigFile', eventConfigFileNameWithoutPath)
        self.sendEvent('UI', 'ui_loadEventConfigFile', eventConfigFileNameWithoutPath)
        self.updateEventConfigInfo()
        # 5. 显示读取成功
        dis = time.strftime('%Y-%m-%d %H:%M:%S, read successfully ', time.localtime(time.time()))
        self.label_display.setText(dis + eventConfigFileNameWithoutPath)

    # 更新这个页面的显示
    def updateEventConfigInfo(self, eventConfigFileName=''):
        try:
            self.configFileName = systemConfig.getEventConfigFilePath()
            self.configHandlers = gtyTypes.ConfigHandlers()
            self.machineId = tools.getMachineId(self.configHandlers.mmc.read("machine", "machineId"))
            self.eventId = self.configHandlers.event.read("event", "eventId")
            self.eventName = self.configHandlers.event.read("event", "eventName")
            self.machinePosition = self.configHandlers.event.read(self.machineId, "machinePosition") + "|" + \
                                   self.configHandlers.event.read(self.machineId, "timingPoint")
            self.recordFileDir = os.path.join(self.configHandlers.machine.read("IO", "dataFileDir"),
                                              self.machineId + "_" + self.eventId)
            # 更新页面显示
            if self.ReeventId == '':
                self.label_machineId.setText(self.eventId)
            else:
                self.label_machineId.setText(f"{self.eventId} -> {self.ReeventId}")
                self.recordFileDir = os.path.join(self.configHandlers.machine.read("IO", "dataFileDir"),
                                                  self.machineId + "_" + self.ReeventId)
            self.label_eventName.setText(self.eventName)
            self.label_machinePosition.setText(self.machinePosition)
            self.label_recordFile.setText(self.recordFileDir)
            self.label_configFile.setText(self.configFileName)
        except Exception as e:
            gtyLog.log.write(__file__, e)
            pass

    # 从服务器下载配置文件
    def downloadConfigFileFromServer(self):
        # 创建一个下载事件交给IO进程去下载
        self.sendEvent('IO', 'web_downloadEventConfigFileFromServer', self.machineId)

    # 下载配置文件完成后的处理
    def loadConfigFileDownloadedFromServer(self, configFileName):
        if 'failed' not in configFileName:
            # 1. 加载赛事配置文件的内容
            print(__file__, "file_loadEventConfigFile...")
            self.sendEvent('IO', 'file_loadEventConfigFile', configFileName)
            dis = time.strftime('%Y-%m-%d %H:%M:%S, ', time.localtime(time.time()))
            self.label_display.setText(dis + configFileName + '\n    download config file Successfully！')
        else:
            print('down load config file failed')
            if configFileName == 'failed':
                self.label_display.setText('Download Config File Failed！')
            else:
                self.label_display.setText('failed: machine not in event.')

    # 上传比赛记录到服务器，上传全部文件
    def uploadRecordFileToServer(self):
        self.uploadRecordFileButton.setDisabled(True)
        self.uploadRecordFileButton.setStyleSheet(systemConfig.param.btnDisabledStyle)
        self.sendEvent('IO', 'web_uploadFileToServer', [True])
        self.label_display.setText("Uploading files to server...")
        print(__file__, "uploadRecordFileToServer")

    # 更新上传结果文件是否成功
    def handleFileUploadResult(self, list):
        import time
        dis = time.strftime('%Y-%m-%d %H:%M:%S, \n', time.localtime(time.time()))
        if list[0] == 'successful':
            self.label_display.setText(dis + language.mainPage_dataFileUploadSuccessful + ". " + list[1] + ".")
        else:
            self.label_display.setText(dis + language.mainPage_dataFileUploadFailed)
        self.uploadRecordFileButton.setEnabled(True)
        self.uploadRecordFileButton.setStyleSheet(systemConfig.param.btnEnabledStyle)

    # 删除数据文件
    def deleteRecord(self):
        self.sendEvent("IO", "io_deleteDataFile", [])

    # 根据文件大小（字节）返回合适的单位格式
    @staticmethod
    def format_size(size):

        if size < 1024:
            return f"{size} B"
        elif size < 1024 ** 2:
            return f"{size / 1024:.2f} KB"
        elif size < 1024 ** 3:
            return f"{size / (1024 ** 2):.2f} MB"
        else:
            return f"{size / (1024 ** 3):.2f} GB"

    # 更新显示复制进度
    def update_progress(self):
        # 先判断复制进度队列是否有数据
        if not copy_file_process_queue.empty():
            copied_size, total_size = copy_file_process_queue.get()
            formatted_copied_size = self.format_size(copied_size)
            formatted_total_size = self.format_size(total_size)
            # 更新界面上的标签
            self.label_display.setText(f"Copying Progress: {formatted_copied_size} / {formatted_total_size}")
        else:
            # 如果复制进度队列没有数据，则判断结果队列是否有数据
            if not copy_file_result_queue.empty():
                self.label_display.setText(copy_file_result_queue.get())
            else:
                # 如果结果队列也没有数据，则停止定时器
                self.timer.stop()
                return

    # 导出数据到u盘
    def exportData2Disk(self, all=False):
        uName = gtyIO.gtyIoTools.getUDiskPath(self)
        if all:
            p = threading.Thread(target=gtyIO.gtyIoTools.copyFileToU_fuc,
                                 args=(uName,'U*', copy_file_result_queue, copy_file_process_queue))
        else:
            p = threading.Thread(target=gtyIO.gtyIoTools.copyFileToU_fuc,
                                 args=(
                                 uName,os.path.basename(self.recordFileDir), copy_file_result_queue, copy_file_process_queue))
        p.start()
        if not self.timer.isActive():
            self.timer.start(100)

    # 自定义赛事号
    def setRandomNum(self):
        w = InputDialog()
        w.exec()
        if w.input_text:
            try:
                self.ReeventId = str(w.input_text)
                with open('./Newevent.ini', 'w') as f:
                    f.write(self.ReeventId)
                    f.close()
                QMessageBox.information(self, "提示", f"set Race ID OK！{self.ReeventId}")
                self.label_display.setText(f"set Race ID to {self.ReeventId}！")
            except Exception as e:
                print(__file__, e)
        else:
            QMessageBox.information(self, "提示", "clear modify Race ID！")
            self.label_display.setText("clear modify Race ID！")
            self.ReeventId = ""
            with open('./Newevent.ini', 'w') as f:
                f.write('')
            return
        self.updateEventConfigInfo()


class InputDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = ui_Inputdialog.Ui_Dialog()
        self.ui.setupUi(self)
        self.initUIconnect()
        self.initsetlanguage()

    def Confirm(self):
        self.input_text = self.ui.Edit_input.text()
        self.close()
        return self.input_text

    def cancel(self):
        self.close()

    # 关联槽函数
    def initUIconnect(self):
        self.ui.pushButton_Confirm.clicked.connect(self.Confirm)
        self.ui.pushButton_cancel.clicked.connect(self.cancel)
        self.ui.Edit_input.returnPressed.connect(self.Confirm)

    def initsetlanguage(self):
        self.ui.pushButton_Confirm.setText(language.eventSetting_pushButton_Confirm)
        self.ui.pushButton_cancel.setText(language.eventSetting_pushButton_Cancel)
        self.ui.Edit_input.setPlaceholderText(language.eventSetting_Edit_input)
        self.ui.label.setText(language.eventSetting_label)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = EventSettingDialog(None, None, None)
    form.show()
    sys.exit(app.exec_())
